package cn.cxyxj.inner_client.filter;


import cn.cxyxj.inner_client.utils.JWTUtil;
import cn.cxyxj.inner_client.utils.RedisUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.jwt.JWT;
import cn.hutool.jwt.JWTPayload;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.CollectionUtils;
import org.springframework.util.PathMatcher;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;

/**
 * 拦截所有请求，判断请求头中是否传递 token 信息
 * @author cxyxj
 */
@Component
public class JwtTokenFilter extends OncePerRequestFilter {

    // 不需要登录就能访问的资源
    private static final Set<String> IGNORE_URL_INCLUDE_FILTERS  = new HashSet<>();


    static {
        IGNORE_URL_INCLUDE_FILTERS.add("/hello");
        IGNORE_URL_INCLUDE_FILTERS.add("/codeLogin");
        IGNORE_URL_INCLUDE_FILTERS.add("/checkLogin");
    }
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {
        String requestURI = request.getRequestURI();
        // 从请求头中获取 token
        String token = request.getHeader("Authorization");
        // 没有 token 则相当于匿名访问，判断是否是开放接口
        // 先从资源中匹配，如果存在，直接放行
        PathMatcher matcher = new AntPathMatcher();
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json;charset=UTF-8");
        if (StrUtil.isBlank(token)) {
            boolean staticUrlFlag = IGNORE_URL_INCLUDE_FILTERS.stream().anyMatch(u -> matcher.match(u, requestURI));
            if(staticUrlFlag){
                chain.doFilter(request, response);
                return;
            }
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            response.getWriter().write("暂未登录，请您登录");
            return;
        }
        // 根据 token 从 Redis 获得用户信息
        Object value = RedisUtil.get(String.format("inner-client-1-token:%s", token));
      
        if (Objects.isNull(value)) {
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            response.getWriter().write("错误的登录信息");
            return;
        }
        JWT jwt = JWTUtil.parseJWT(value.toString());
        JWTPayload payload = jwt.getPayload();
        List<String> urlSet = payload.getClaimsJson().getBeanList("urlSet", String.class);
        if(CollectionUtils.isEmpty(urlSet)) {
            response.setStatus(HttpServletResponse.SC_FORBIDDEN);
            response.getWriter().write("没有权限");
            return;
        }
        // JSONObject jsonObject = JSONObject.parseObject(value);
      //  JSONArray array = jsonObject.getJSONArray("urlSet");
      //  List<String> urlSet = array.toJavaList(String.class);
        boolean flag = urlSet.stream().anyMatch(url -> matcher.match(url, requestURI));
        if(flag){
            chain.doFilter(request, response);
            return;
        }
        response.setStatus(HttpServletResponse.SC_FORBIDDEN);
        response.getWriter().write("没有权限");
        return;
    }
}

